const config = require('../config');

/**
 * 统一错误响应格式
 * @param {Object} err - 错误对象
 * @param {Object} req - Express请求对象
 * @param {Object} res - Express响应对象
 * @param {Function} next - 下一个中间件
 */
function errorHandler(err, req, res, next) {
  // 获取错误状态码，默认为500
  const statusCode = err.statusCode || config.app.response.errorCode;
  
  // 构建错误响应数据
  const errorResponse = {
    success: false,
    code: statusCode,
    message: err.message || '服务器内部错误',
    // 开发环境显示详细错误信息，生产环境隐藏
    details: config.app.environment === 'development' ? err.stack : undefined,
    timestamp: new Date().toISOString(),
    path: req.path,
    method: req.method
  };
  
  // 记录错误日志
  console.error(`[${statusCode}] ${req.method} ${req.path} - ${err.message}`);
  if (config.app.environment === 'development') {
    console.error(err.stack);
  }
  
  // 发送错误响应
  res.status(statusCode).json(errorResponse);
}

/**
 * 404错误处理中间件
 * @param {Object} req - Express请求对象
 * @param {Object} res - Express响应对象
 * @param {Function} next - 下一个中间件
 */
function notFoundHandler(req, res, next) {
  const error = new Error(`请求的路径 ${req.originalUrl} 不存在`);
  error.statusCode = config.app.response.notFoundCode;
  next(error);
}

/**
 * 验证错误处理中间件
 * @param {Object} err - 错误对象
 * @param {Object} req - Express请求对象
 * @param {Object} res - Express响应对象
 * @param {Function} next - 下一个中间件
 */
function validationErrorHandler(err, req, res, next) {
  // 检查是否是express-validator的验证错误
  if (err.array) {
    const validationErrors = err.array();
    const error = new Error('请求数据验证失败');
    error.statusCode = config.app.response.validationErrorCode;
    error.details = validationErrors.map(e => ({
      field: e.path,
      message: e.msg
    }));
    return next(error);
  }
  next(err);
}

/**
 * 数据库错误处理中间件
 * @param {Object} err - 错误对象
 * @param {Object} req - Express请求对象
 * @param {Object} res - Express响应对象
 * @param {Function} next - 下一个中间件
 */
function databaseErrorHandler(err, req, res, next) {
  // 检查是否是数据库错误
  if (err.name === 'SequelizeError' || err.name === 'SequelizeValidationError') {
    const error = new Error('数据库操作失败');
    error.statusCode = 400;
    error.details = err.errors ? err.errors.map(e => e.message) : undefined;
    return next(error);
  }
  next(err);
}

/**
 * JWT错误处理中间件
 * @param {Object} err - 错误对象
 * @param {Object} req - Express请求对象
 * @param {Object} res - Express响应对象
 * @param {Function} next - 下一个中间件
 */
function jwtErrorHandler(err, req, res, next) {
  // 检查是否是JWT错误
  if (err.name === 'JsonWebTokenError' || err.name === 'TokenExpiredError') {
    const error = new Error('认证失败：无效或过期的令牌');
    error.statusCode = config.app.response.unauthorizedCode;
    return next(error);
  }
  next(err);
}

module.exports = {
  errorHandler,
  notFoundHandler,
  validationErrorHandler,
  databaseErrorHandler,
  jwtErrorHandler,
  
  // 应用所有错误处理中间件的函数
  applyErrorMiddleware: (app) => {
    // 验证错误处理
    app.use(validationErrorHandler);
    // 数据库错误处理
    app.use(databaseErrorHandler);
    // JWT错误处理
    app.use(jwtErrorHandler);
    // 404错误处理
    app.use(notFoundHandler);
    // 全局错误处理
    app.use(errorHandler);
  }
};

// 默认导出全局错误处理中间件
module.exports.default = errorHandler;